package com.wgt.startx;

import com.wgt.startx.bean.Data;
import com.wgt.startx.bean.Handler;
import com.wgt.startx.bean.Param;
import com.wgt.startx.bean.View;
import com.wgt.startx.helper.BeanHelper;
import com.wgt.startx.helper.ConfigHelper;
import com.wgt.startx.helper.ControllerHelper;
import com.wgt.startx.util.*;
import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by wgt on 2017/7/30.
 */
@WebServlet(urlPatterns = "/*",loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet {

    public void init(ServletConfig servletConfig) throws ServletException{
        //初始化所有helper
        HelperLoad.init();
        //获取ServerContext对象
        ServletContext context = servletConfig.getServletContext();

        //注册处理jsp的Servlet
        ServletRegistration jspServlet = context.getServletRegistration("jsp");
        jspServlet.addMapping(ConfigHelper.getAppJsp()+"*");

        //注册处理静态资源的Servlet
        ServletRegistration asSetServlet = context.getServletRegistration("default");
        asSetServlet.addMapping(ConfigHelper.getAppAssetPath()+"*");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestMethod = req.getMethod().toLowerCase();
        String requestPath = req.getPathInfo();

        //获取RequestMapping
        Handler handler = ControllerHelper.getHandler(requestMethod.toLowerCase(),requestPath);
        if (handler!=null){
            //获取Controller类和实例对象
            Class<?> controllerClass = handler.getControllerClass();
            Object controller = BeanHelper.getBean(controllerClass);

            //创建请求参数
            Map<String,Object> paramMap= new HashMap<String,Object>();
            Enumeration<String> paramNames = req.getParameterNames();
            while (paramNames.hasMoreElements()){
                String paramName = paramNames.nextElement();
                String paramValue = req.getParameter(paramName);
                paramMap.put(paramName,paramValue);
            }
            String body = CodecUtil.decodeURL(StreamUtil.getString(req.getInputStream()));
            if (StringUtils.isNotEmpty(body)){
                String[] params = StringUtils.split(body,"&");
                if (CollectionUtils.isNotEmpty(params)){
                    for(String param : params) {
                        String[] array = StringUtils.split(param, "=");
                        if (CollectionUtils.isNotEmpty(array)&&array.length==2){
                            String paramName = array[0];
                            String paramValue = array[1];
                            paramMap.put(paramName,paramValue);
                        }
                    }
                }
            }

            Method actionMethod = handler.getActionMethod();
            Object result = null;
            //构建参数模型
            if (paramMap.size()>0){
                Param param = new Param(paramMap) ;
                //调用action方法

                result = ReflectionUtil.invokeMethod(controller,actionMethod,param);
            }else{
                result = ReflectionUtil.invokeMethod(controller,actionMethod,null);
            }
            /*Param param = new Param(paramMap) ;
            //调用action方法
            Method actionMethod = handler.getActionMethod();
            Object result = ReflectionUtil.invokeMethod(controller,actionMethod,param);*/

            if (result instanceof View){
                View view = (View) result;
                String path = view.getPath();
                if (StringUtils.isNotEmpty(path)){
                    if(path.startsWith("/")){
                        resp.sendRedirect(req.getContextPath()+path);
                    }else{
                        Map<String,Object> model = view.getModel();
                        for(Map.Entry<String,Object> entry:model.entrySet()){
                            req.setAttribute(entry.getKey(),entry.getValue());
                        }
                        req.getRequestDispatcher(path).forward(req,resp);
                    }
                }
            }

            if (result instanceof Data){
                Data data = (Data)result;
                Object model = data.getModel();
                if(model != null){
                    resp.setContentType("application/json");
                    resp.setCharacterEncoding("UTF-8");
                    PrintWriter out = resp.getWriter();
                    String json = JsonUtil.toJson(model);
                    out.write(json);
                    out.flush();
                    out.close();
                }
            }
        }
    }


}
